using System;
using System.Globalization;



namespace Waymex.Gps.Nmea
{
	/// <summary>
	/// RMC NMEA sentence class.
	/// </summary>
	sealed public class SentenceRmc : Sentence
	{
		private const string C_SENTENCE_TYPE = "RMC";
		
		private bool m_blnNavigationWarning = false;
		private double m_dblLatitude = 0.0;
		private double m_dblLongitude = 0.0;
		private double m_dblSpeed = 0.0;
		private double m_dblTrackMadeGood = 0.0;
        private System.DateTime m_dtDateTime = Convert.ToDateTime("01 Jan 0001", CultureInfo.InvariantCulture);
		private double m_dblMagVariation = 0.0;

        /// <summary>
        /// Constructor for the class.
        /// </summary>
        /// <param name="sentence">NMEA sentence.</param>
        public SentenceRmc(string sentence)
            : base(sentence)
		{
			try
			{
				//check the type to ensure that we can continue
				if(this.TypeId.ToUpper(CultureInfo.InvariantCulture) == C_SENTENCE_TYPE)
				{
					Populate(sentence);
				}
				else
				{
					throw new InvalidSentence(C_MSG_001);
				}
			}
			catch(Exception e)
			{
                throw new InvalidSentence(e.Message, e);
			}
		}

		private void Populate(string p_strSentence)
		{
			string strDateTime = "";

			try
			{
				//element [0] already done in the base class
				if(SentenceItemExists(2))
				{
					if(m_astrSentence[2].ToUpper(CultureInfo.InvariantCulture) == "A") //A = OK, V = Invalid
					{
						m_blnNavigationWarning = false;
					}
					else
					{
						m_blnNavigationWarning = true;
					}
				}
				else
				{
						m_blnNavigationWarning = false;
				}
				if(SentenceItemExists(4)) m_dblLatitude = FormatPosition(m_astrSentence[3] + m_astrSentence[4]);
				if(SentenceItemExists(6)) m_dblLongitude = FormatPosition(m_astrSentence[5] + m_astrSentence[6]);
				if(SentenceItemExists(7)) m_dblSpeed = FormatNumber(m_astrSentence[7]);
				if(SentenceItemExists(8)) m_dblTrackMadeGood = FormatNumber(m_astrSentence[8]);
				
				if(SentenceItemExists(9))
				{
					strDateTime = FormatDate(m_astrSentence[9]) + " " + FormatTime(m_astrSentence[1]);
                    m_dtDateTime = Convert.ToDateTime(strDateTime, CultureInfo.InvariantCulture);
				}
				if(SentenceItemExists(10)) m_dblMagVariation = FormatNumber(m_astrSentence[10]);
         
				if(SentenceItemExists(11))
				{
					if(m_astrSentence[11].ToUpper(CultureInfo.InvariantCulture) == "W" || m_astrSentence[11] == "S")
					{
						m_dblMagVariation = m_dblMagVariation * -1.0;
					}
				}
			}
			catch(Exception e)
			{
                throw new InvalidSentence(e.Message, e);
			}
		}	
	
		///<summary>
		///Returns the Latitude in Degrees. Negative values indicate positions West.
		///</summary>
		public double Latitude
		{
			get
			{
				return m_dblLatitude;
			}
		}

		///<summary>
		///Returns the Longitude in Degrees. Negative values indicate positions South.
		///</summary>
		public double Longitude
		{
			get
			{
				return m_dblLongitude;
			}
		}

		///<summary>
		///Returns the speed over ground in Knots.
		///</summary>
		public double Speed
		{
			get
			{
				return m_dblSpeed;
			}
		}

		///<summary>
		///Returns the Track Made Good in degrees true.
		///</summary>
		public double TrackMadeGood
		{
			get
			{
				return m_dblTrackMadeGood;
			}
		}

		///<summary>
		///Returns the Magnetic Variation in Degrees.
		///</summary>
		public double MagneticVariation
		{
			get
			{
				return m_dblMagVariation;
			}
		}
		///<summary>
		///Returns true if a Receiver Navigation Warning is present.
		///</summary>
		public bool NavigationWarning
		{
			get
			{
				return m_blnNavigationWarning;
			}
		}

		///<summary>
		///Returns the date and time (UTC).
		///</summary>
		public System.DateTime DateTime
		{
			get
			{
				return m_dtDateTime;
			}
		}
	}
}
